<!DOCTYPE html>
<html lang="zh-CN">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Miniblink Vue3 兼容版</title>
    <style>
      /* 基础样式 */
      * {
        box-sizing: border-box;
        margin: 0;
        padding: 0;
      }
      
      body {
        font-family: Arial, "Microsoft YaHei", sans-serif;
        line-height: 1.6;
        color: #333;
        background-color: #f5f7fa;
        overflow: hidden;
      }
      
      #app {
        min-height: 100vh;
        width: 100%;
        position: relative;
        overflow: hidden;
        text-align: left;
        background-color: #ffffff; /* 默认背景色 */
      }
      
      /* 加载状态 */
      .loading-container, .error-container {
        display: flex;
        align-items: center;
        justify-content: center;
        height: 100vh;
        width: 100%;
        background-color: #f5f7fa;
        flex-direction: column;
        position: absolute;
        top: 0;
        left: 0;
        z-index: 9999;
      }
      
      .loading-message, .error-title {
        color: #409EFF;
        font-size: 24px;
        margin-bottom: 20px;
      }
      
      /* 错误状态 */
      .error-message {
        color: #F56C6C;
        font-size: 18px;
        margin-bottom: 10px;
      }
      
      /* 确保组件绝对定位 */
      [data-component-id] { position: absolute !important; box-sizing: border-box !important; }
      
      /* 修复单选框和多选框组样式 */
      .el-radio-group, .el-checkbox-group {
        display: flex !important;
        flex-wrap: wrap !important;
        gap: 5px !important;
        align-items: flex-start !important;
      }
      
      /* 确保单选框和多选框组内的元素样式正确 */
      .el-radio-group > .el-radio, 
      .el-checkbox-group > .el-checkbox,
      .el-radio-group > [data-component-id], 
      .el-checkbox-group > [data-component-id] {
        position: relative !important;
        margin: 0 !important;
        width: auto !important; /* 明确指定auto，不使用100% */
        height: auto !important; /* 明确指定auto，不使用100% */
        flex-shrink: 0 !important;
        top: auto !important;
        left: auto !important;
        z-index: auto !important;
        /* 明确禁止使用100%宽高 */
        max-width: none !important;
        max-height: none !important;
      }
      
      /* 确保单选框和多选框元素本身不使用100%宽高 */
      .el-radio, .el-checkbox {
        width: auto !important;
        height: auto !important;
      }
      
      /* 用户自定义样式 */
      <% if (typeof componentStyles === 'string' && componentStyles.length > 0) { %>
        <style id="custom-compat-styles">
          <%- componentStyles %>
        </style>
      <% } %>
    </style>
    
    <!-- 引入Vue3 (CDN) -->
    <script src="https://unpkg.com/vue@3/dist/vue.global.prod.js"></script>
  </head>
  <body>
    <div id="app">
      <!-- Vue application will be mounted here -->
      <div class="loading-container">
        <div class="loading-message">加载中...</div>
      </div>
    </div>

    <script>
      // 通信桥接 - 与Miniblink/外部应用通信
      window.miniBridge = {
        // 事件处理器存储
        _eventHandlers: {},
        
        // 注册事件处理器
        on: function(eventName, handler) {
          if (!this._eventHandlers[eventName]) {
            this._eventHandlers[eventName] = [];
          }
          this._eventHandlers[eventName].push(handler);
          console.log("Registered handler for event: " + eventName);
          return this;
        },
        
        // 移除事件处理器
        off: function(eventName, handler) {
          if (!this._eventHandlers[eventName]) return this;
          
          if (handler) {
            const index = this._eventHandlers[eventName].indexOf(handler);
            if (index !== -1) {
              this._eventHandlers[eventName].splice(index, 1);
            }
          } else {
            // 移除所有该事件处理器
            delete this._eventHandlers[eventName];
          }
          
          return this;
        },
        
        // 向主应用发送事件
        emit: function(eventName, data) {
          console.log("Emitting event: " + eventName, data);
          
          try {
            // 对于Miniblink/CEF集成
            if (window.external && typeof window.external.CallCSharpOrOther === 'function') {
              const message = JSON.stringify({
                event: eventName,
                data: data || {}
              });
              window.external.CallCSharpOrOther(message);
            } 
            // 浏览器调试环境
            else {
              console.warn("No host bridge available for event: " + eventName);
              
              // 在浏览器环境中ready事件的特殊处理
              if (eventName === 'ready') {
                // 在浏览器中，模拟测试数据的响应
                setTimeout(function() {
                  this._handleHostMessage({
                    event: 'updateRootComponent',
                    data: {
                      id: 'root',
                      type: 'div',
                      style: 'padding: 20px;',
                      children: [
                        {
                          id: 'test-card',
                          type: 'el-card',
                          props: {
                            header: '测试卡片'
                          },
                          style: '',
                          children: [
                            {
                              id: 'test-button',
                              type: 'el-button',
                              props: {
                                type: 'primary',
                                text: '测试按钮'
                              },
                              style: ''
                            }
                          ]
                        }
                      ]
                    }
                  });
                }.bind(this), 500);
              }
            }
          } catch (error) {
            console.error("Error emitting event " + eventName + ":", error);
          }
          
          return this;
        },
        
        // 处理从主应用收到的消息
        _handleHostMessage: function(message) {
          try {
            var eventData;
            if (typeof message === 'string') {
              eventData = JSON.parse(message);
            } else {
              eventData = message;
            }
            
            var event = eventData.event;
            var data = eventData.data;
            
            console.log("Received host event: " + event, data);
            
            if (this._eventHandlers[event]) {
              var handlers = this._eventHandlers[event];
              for (var i = 0; i < handlers.length; i++) {
                try {
                  handlers[i](data);
                } catch (handlerError) {
                  console.error("Error in handler for " + event + ":", handlerError);
                }
              }
            }
          } catch (error) {
            console.error("Error processing host message:", error);
          }
        }
      };
      
      // 处理来自C#/易语言等的消息
      window.MiniblinkCallback = function(messageStr) {
        try { window.miniBridge._handleHostMessage(messageStr); } catch (error) { console.error("Error in MiniblinkCallback:", error); }
      };
      
      // --- App State --- 使用 reactive
      // 先处理 EJS 模板变量
      let initialCompatState = { components: [], canvasSize: { width: 800, height: 600 } };
      try {
          const initialCompatStateJSON = <%- JSON.stringify({ components: components || [], canvasSize: canvasSize || { width: 800, height: 600 } }) %>;
          initialCompatState = JSON.parse(JSON.stringify(initialCompatStateJSON));
      } catch (e) {
          console.error('[Init Compat] Failed to parse initial state JSON:', e);
      }

      window.appState = Vue.reactive({
        components: initialCompatState.components,
        componentStates: {},
        canvasSize: initialCompatState.canvasSize,
        errorMessage: null,
        isLoading: true
      });
      
      // 错误处理函数
      function handleError(error, errorTitle = '错误') {
        console.error('App error:', error);
        const appDiv = document.getElementById('app');
        const errorDiv = document.createElement('div');
        errorDiv.className = 'error-container'; // 使用新的类名
        errorDiv.innerHTML = `
          <div class="error-title">${errorTitle}</div>
          <div class="error-message">${error.message || String(error)}</div>
        `;
        if(appDiv) appDiv.appendChild(errorDiv);
        if(window.miniBridge) window.miniBridge.emit('app:error', { message: error.message || String(error), stack: error.stack });
        window.appState.errorMessage = error.message || String(error);
        window.appState.isLoading = false;
        const loadingEl = document.querySelector('.loading-container');
        if (loadingEl) loadingEl.style.display = 'none';
      }
      
      // 初始化设置 #app 尺寸和样式
      function setAppSizeAndStyle() {
        if (!window.appState.canvasSize) return;
        const appEl = document.getElementById('app');
        if (appEl) {
          appEl.style.setProperty('width', `${window.appState.canvasSize.width}px`, 'important');
          appEl.style.setProperty('height', `${window.appState.canvasSize.height}px`, 'important');
          appEl.style.setProperty('position', 'relative', 'important');
          appEl.style.setProperty('overflow', 'hidden', 'important');
          console.log(`设置app尺寸为: ${window.appState.canvasSize.width}x${window.appState.canvasSize.height}`);
        }
      }

      // 应用初始化函数
      function initializeApp() {
        try {
          if (typeof Vue === 'undefined') {
            throw new Error('Vue未加载，请检查网络连接或CDN');
          }
          
          const { createApp, h, reactive, computed, onMounted, resolveComponent, nextTick } = Vue;
          
          // DynamicRenderer component - 使用 resolveComponent 或 h 创建元素
          const DynamicRenderer = {
            name: 'DynamicRenderer',
            props: {
              component: { type: Object, required: true },
              isInsideGroup: { type: Boolean, default: false }
            },
            setup(props) {
              // 组件状态代理 (简化，不处理复杂 v-model)
              const componentState = computed({
                get: () => window.appState.componentStates[props.component.id],
                set: (value) => {
                  window.appState.componentStates[props.component.id] = value;
                  window.miniBridge.emit('component:change', { componentId: props.component.id, value: value });
                }
              });
              return { componentState };
            },
            render() {
              if (!this.component || !this.component.type) {
                console.error('Invalid component data:', this.component);
                return null;
              }
              
              let componentToRender;
              try {
                componentToRender = resolveComponent(this.component.type);
              } catch(e) {
                console.warn(`Component type "${this.component.type}" could not be resolved, rendering as a plain HTML tag.`);
                componentToRender = this.component.type;
              }
              
              let propsData = Object.assign({}, this.component.props);
              const componentId = this.component.id;
              const componentType = this.component.type;
              
              // --- 事件处理 (简化) ---
              const events = {
                onClick: (event) => {
                  window.miniBridge.emit('component:event', { componentId: componentId, eventName: 'click' });
                  if(event) event.stopPropagation();
                },
                onInput: (event) => { // 基础 input 事件处理
                  const value = event.target.value;
                  this.componentState = value; // 更新状态
                  window.miniBridge.emit('component:event', { componentId: componentId, eventName: 'input', value: value });
                }
                // 其他事件可以按需添加
              };
              
              // --- v-model 状态初始化与绑定 (简化) ---
              if (window.appState.componentStates[componentId] === undefined) {
                let defaultValue = propsData.value ?? propsData.modelValue ?? null;
                 // 特定组件默认值 (简化)
                 if (defaultValue === null && (componentType === 'el-switch' || componentType === 'el-checkbox')) {
                      defaultValue = false;
                 } else if (defaultValue === null && (componentType === 'el-slider' || componentType === 'el-rate')) {
                     defaultValue = 0;
                 }
                 window.appState.componentStates[componentId] = defaultValue;
              }
              
              const vModelProps = {
                modelValue: this.componentState, // 依赖 computed
                'onUpdate:modelValue': (value) => { this.componentState = value; } // 触发 computed set
              };
              
              // --- 子节点/插槽处理 (优化按钮文本) ---
              let children = null;
              let slots = {};
              
              if (this.component.children && this.component.children.length > 0) {
                children = this.component.children.map(child => {
                  const isInsideGroup = componentType === 'el-radio-group' || componentType === 'el-checkbox-group';
                  return h(DynamicRenderer, { component: child, key: child.id, isInsideGroup: isInsideGroup });
                });
              } else if (propsData.textContent) {
                children = propsData.textContent;
                delete propsData.textContent;
              } else if (propsData.label && componentType === 'el-button') { // 主要针对按钮
                children = propsData.label;
              } else if (propsData.text && componentType === 'el-button') {
                children = propsData.text;
              }
              
              if (children !== null) {
                slots.default = () => children;
              }

              // --- 最终 Props 准备 ---
              let style = this.component.style || {};
              if (this.$attrs.isInsideGroup) {
                // 提取并删除 left, top, position 属性
                var left = style.left;
                var top = style.top;
                var position = style.position;
                var restStyle = Object.assign({}, style);
                delete restStyle.left;
                delete restStyle.top;
                delete restStyle.position;
                
                style = Object.assign({}, restStyle, { position: 'relative' }); 
              } 
              // 为 Group 添加 Flex 布局
              else if (componentType === 'el-radio-group' || componentType === 'el-checkbox-group') {
                style = Object.assign({}, style, {
                  display: 'flex',
                  flexDirection: 'row',
                  flexWrap: 'wrap',
                  gap: '5px' // 减小间距，更接近设计时效果
                });
              }

              const finalProps = Object.assign({},
                propsData || {},
                events || {},
                {'data-component-id': componentId, style: style},
                // 尝试为兼容模式添加 v-model，但不保证所有组件都支持
                vModelProps || {}
              );
              
              // 移除冗余 value
              if (finalProps.value !== undefined && finalProps.modelValue !== undefined) {
                delete finalProps.value;
              }
              
              // 兼容模式下，Select 的 options 无法自动渲染为 el-option
              // 宿主应用可能需要监听 select 的事件并动态提供 options
              if (componentType === 'el-select' && finalProps.options) {
                // console.warn("Compatibility mode: ElSelect options rendering might be limited.");
                // 可以尝试将 options 作为普通属性传递，但功能受限
              }

              // 修改 h 函数调用：如果 children 是字符串，可能需要包装（兼容模式简化处理）
              let finalChildren = null;
              if (Array.isArray(children)) {
                  finalChildren = { default: () => children };
              } else if (typeof children === 'string' && children.trim() !== '') {
                   // 兼容模式下，通常直接传递文本即可，按钮可能需要特殊处理，但这里简化
                  finalChildren = children;
              }

              return h(componentToRender, finalProps, finalChildren);
            }
          };
          
          // App component - 保持结构，使用新的 DynamicRenderer
          const App = {
            setup() {
              const state = reactive({
                rootComponent: null,
                errorMessage: window.appState.errorMessage
              });
              
              onMounted(() => {
                try {
                  // 创建根容器
                  state.rootComponent = {
                    id: 'root',
                    type: 'div',
                    style: `width: 100%; height: 100%; position: relative; left: 0; top: 0; margin: 0; padding: 0; overflow: hidden;`,
                    children: Array.isArray(window.appState.components) ? window.appState.components : []
                  };
                  
                  // 设置画布大小
                  const canvasSize = window.appState.canvasSize;
                  setAppSizeAndStyle(); // 使用新函数
                  
                  // 使用 nextTick 确保 DOM 就绪后再设置尺寸 (兼容模式)
                  nextTick(() => {
                    setAppSizeAndStyle(); // 重复调用以确保应用成功
                  });
                  
                  window.appState.isLoading = false;
                  const loadingEl = document.querySelector('.loading-container');
                  if (loadingEl) loadingEl.style.display = 'none';
                  
                  // 订阅宿主消息
                  window.miniBridge.on('updateComponents', (newComponents) => {
                    window.appState.components = newComponents || [];
                    state.rootComponent = { ...state.rootComponent, children: window.appState.components };
                  });
                  
                  window.miniBridge.on('updateComponentState', (data) => {
                    if(data && data.componentId && data.value !== undefined) {
                      window.appState.componentStates[data.componentId] = data.value;
                    }
                  });
                  
                  window.miniBridge.on('error', (error) => { handleError(error, 'Host Error'); });
                  
                  window.miniBridge.emit('ready');
                  console.log('Vue 3 Compat application initialized and ready.');
                  
                } catch (initError) {
                  handleError(initError, '兼容模式初始化失败');
                }
              });
              
              return () => {
                if (state.errorMessage) {
                  return h('div', { class: 'error-container' }, [
                    h('div', { class: 'error-title' }, '错误'),
                    h('div', { class: 'error-message' }, state.errorMessage)
                  ]);
                }
                if (!state.rootComponent) {
                  return h('div', { class: 'loading-container' }, [
                    h('div', { class: 'loading-message' }, '加载中...')
                  ]);
                }
                // 直接渲染根组件，DynamicRenderer会处理子组件
                return h(DynamicRenderer, { component: state.rootComponent }); 
              };
            }
          };
          
          // Create and mount the app
          const app = createApp(App);
          // 注意：这里不执行 app.use(ElementPlus)
          app.mount('#app');
          
        } catch (error) {
          handleError(error, '兼容模式核心初始化失败');
        }
      }
      
      // Start initialization on DOMContentLoaded
      document.addEventListener('DOMContentLoaded', initializeApp);
    </script>
  </body>
</html> 